package com.weixin.project.Controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weixin.project.Common.Enum.ModuleType;
import com.weixin.project.Common.Enum.UserType;
import com.weixin.project.Entity.Danmu;
import com.weixin.project.Entity.User;
import com.weixin.project.Entity.UserFavVideo;
import com.weixin.project.Entity.Video;
import com.weixin.project.Service.MsgService;
import com.weixin.project.Service.OSSService;
import com.weixin.project.Service.UserService;
import com.weixin.project.Service.VideoService;
import com.weixin.project.Util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
public class VideoController {
    @Autowired
    VideoService videoService;
    @Autowired
    UserService userService;
    @Autowired
    OSSService ossService;
    @Autowired
    MsgService msgService;
    @Value("${logging.pattern.dateformat}")
    String dateFormat;

    @PostMapping("/video/upload_video")
    public JSONObject uploadVideo(HttpServletRequest request,
                                  @RequestBody JSONObject params){
        User currentUser = userService.findCurrentUser(request);
        Video video = new Video();
        video.setTitle(params.getString("title"));
        video.setVideoSrc(params.getString("video_src"));
        video.setCoverSrc(params.getString("cover_src"));
        video.setDescription(params.getString("description"));
        video.setUserId(currentUser.getId());
        video.setModule(ModuleType.codeOf(params.getInteger("type")));
        video.setQuestionId(params.getInteger("id"));
        video.setCreateTime(new Date());
        videoService.storeVideo(video);
        return ResponseUtil.success();
    }

    @GetMapping("/video/get_video")
    public JSONObject getVideo(HttpServletRequest request,
                               @RequestParam("id") Integer id){
        User currentUser = userService.findCurrentUser(request);
        Video video = videoService.findVideo(id);
        JSONObject ret = new JSONObject();
        User author = userService.findUser(video.getUserId());
        ret.put("video_src", video.getVideoSrc());
        ret.put("cover_src", video.getCoverSrc());
        ret.put("id", video.getId());
        ret.put("title", video.getTitle());
        ret.put("description", video.getDescription());
        ret.put("danmu_count", videoService.countDanmusOfVideo(video.getId()));
        ret.put("favorite_count", videoService.countFavoritesOfVideo(video.getId()));
        ret.put("open_count",video.getOpenCount());
        ret.put("user_src", author.getImage());
        ret.put("user_name", author.getName());
        ret.put("user_id", author.getId());
        ret.put("is_favorite", videoService.isFavorite(currentUser.getId(), video.getId()));
        ret.put("type", video.getModule().getValue());
        ret.put("type_id", video.getQuestionId());
        videoService.incOpenCount(video.getId());
        return ResponseUtil.success("", ret);
    }

    @PostMapping("/video/send_danmu")
    public JSONObject sendDanMu(@RequestBody JSONObject params){
        Danmu danmu = new Danmu();
        danmu.setVideoId(params.getInteger("id"));
        danmu.setText(params.getString("text"));
        danmu.setColor(params.getString("color"));
        danmu.setTime(params.getInteger("time"));
        videoService.storeDanmu(danmu);
        return ResponseUtil.success();
    }

    @GetMapping("/video/get_danmu")
    public JSONObject getDanmuList(@RequestParam("id") Integer videoId){
        List<Danmu> danmus = videoService.findAllDanmuOfVideo(videoId);
        JSONArray arr = new JSONArray();
        for (Danmu danmu:danmus){
            JSONObject obj = new JSONObject();
            obj.put("text", danmu.getText());
            obj.put("color", danmu.getColor());
            obj.put("time", danmu.getTime());
            arr.add(obj);
        }
        JSONObject ret = new JSONObject();
        ret.put("danmu_list", arr);
        return ret;
    }

    @Deprecated
    @PostMapping("/upload-video")
    public JSONObject uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        try {
            return ResponseUtil.success("", ossService.uploadVideo(file));
        } catch (Exception exception) {
            return ResponseUtil.error(exception.toString());
        }
    }

    @CrossOrigin(origins = "*", allowedHeaders = "*")
    @GetMapping("/download-video/{fileName:.+}")
    public Resource downloadFile(@PathVariable String fileName) {
        return ossService.downloadVideo(fileName);
    }

    @PostMapping("/video/favorite")
    public JSONObject favoriteVideo(HttpServletRequest request,
                                    @RequestBody JSONObject params){
        User currentUser = userService.findCurrentUser(request);
        Integer videoId = params.getInteger("id");
        Video video = videoService.findVideo(videoId);
        if (video == null) return ResponseUtil.error("不存在的视频id");
        videoService.userFavoriteVideo(currentUser.getId(), videoId);
        return ResponseUtil.success("");
    }

    @GetMapping("/video/get_video_list")
    public JSONObject getAllVideo(@RequestParam("page") Integer page){
        page -- ;
        Page<Video> videoPage = videoService.findAllVideos(page);
        JSONObject ret = new JSONObject();
        ret.put("all_pages", videoPage.getTotalPages());
        List<Video> videos = videoPage.getContent();
        JSONArray array = new JSONArray();
        for (Video video :
                videos) {
            JSONObject obj = new JSONObject();
            obj.put("cover_src", video.getCoverSrc());
            obj.put("time", new SimpleDateFormat(dateFormat).format(video.getCreateTime()));
            obj.put("id", video.getId());
            obj.put("title", video.getTitle());
            Integer userId = video.getUserId();
            User user = userService.findUser(userId);
            obj.put("user", user.getName());
            obj.put("user_src", user.getImage());
            array.add(obj);
        }
        ret.put("all_videos", videoService.countAllVideos());
        ret.put("video", array);
        return ResponseUtil.success("", ret);
    }

    @GetMapping("/video/get_my_video")
    public JSONObject getMyVideo(HttpServletRequest request){
        User currentUser = userService.findCurrentUser(request);
        List<Video> videos = videoService.findVideosOfUser(currentUser.getId());
        JSONArray array = new JSONArray();
        for (Video video :
                videos) {
            JSONObject obj = new JSONObject();
            obj.put("cover_src", video.getCoverSrc());
            obj.put("id", video.getId());
            obj.put("title", video.getTitle());
            obj.put("description", video.getDescription());
            obj.put("time", new SimpleDateFormat(dateFormat).format(video.getCreateTime()));
            User user = userService.findUser(video.getUserId());
            obj.put("user", user.getName());
            obj.put("user_src", user.getImage());
            array.add(obj);
        }
        JSONObject ret = new JSONObject();
        ret.put("video", array);
        ret.put("count", videoService.countOriginVideosOfUser(currentUser.getId()));
        return ResponseUtil.success("", ret);
    }

    @PostMapping("/video/delete_my_video")
    public JSONObject deleteVideo(HttpServletRequest request,
                                  @RequestBody JSONObject params){
        User currentUser = userService.findCurrentUser(request);
        Integer videoId = params.getInteger("id");
        Video video = videoService.findVideo(videoId);
        if (!currentUser.getType().equals(UserType.ADMIN) && video.getUserId() != currentUser.getId())  return ResponseUtil.accessError();
        videoService.deleteVideo(video);
        //自己删除自己的东西不用发消息
        if (!currentUser.getId().equals(video.getUserId())){
            msgService.sendDeleteMessage(video.getUserId(), "Video", video.getTitle());
        }
        return ResponseUtil.success("");
    }

    @GetMapping("/video/get_favorite")
    public JSONObject getFavVideo(HttpServletRequest request,
                                  @RequestParam("page") Integer page){
        User currentUser = userService.findCurrentUser(request);
        page -- ;
        JSONObject ret = new JSONObject();
        Page<UserFavVideo> videoPage = videoService.findFavVideosOfUser(currentUser.getId(), page);
        ret.put("all_pages", videoPage.getTotalPages());
        List<Video> videos = videoPage.getContent().stream().map(x -> videoService.findVideo(x.getVideoId())).collect(Collectors.toList());
        JSONArray array = new JSONArray();
        for (Video video :
                videos) {
            JSONObject obj = new JSONObject();
            obj.put("cover_src", video.getCoverSrc());
            obj.put("time", new SimpleDateFormat(dateFormat).format(video.getCreateTime()));
            obj.put("id", video.getId());
            obj.put("title", video.getTitle());
            User user = userService.findUser(video.getUserId());
            obj.put("user", user.getName());
            obj.put("user_src", user.getImage());
            array.add(obj);
        }
        ret.put("video", array);
        ret.put("count", videoService.countFavVideosOfUser(currentUser.getId()));
        return ResponseUtil.success("", ret);

    }

    @GetMapping("/video/search")
    public JSONObject searchVideo(HttpServletRequest request,
                                  @RequestParam("text") String text){
        List<Video> videos = videoService.searchVideos(text);
        JSONArray array = new JSONArray();
        for (Video video:videos){
            JSONObject obj = new JSONObject();
            obj.put("id", video.getId());
            obj.put("cover_src", video.getCoverSrc());
            User user = userService.findUser(video.getUserId());
            obj.put("user_src", user.getImage());
            obj.put("user_name", user.getName());
            obj.put("title", video.getTitle());
            array.add(obj);
        }
        JSONObject ret = new JSONObject();
        ret.put("videos", array);
        return ResponseUtil.success("", ret);
    }

    @GetMapping("/video/test_video")
    public JSONObject getVideoByModule(@RequestParam("id") Integer questionId,
                                       @RequestParam("module") Integer moduleId){
        List<Video> videos = videoService.findVideosByModule(ModuleType.codeOf(moduleId));
        JSONArray array = new JSONArray();
        for (Video video:videos){
            JSONObject obj = new JSONObject();
            obj.put("video_id", video.getId());
            obj.put("video_cover", video.getCoverSrc());
            obj.put("video_title", video.getTitle());
            User user = userService.findUser(video.getUserId());
            obj.put("video_user_name", user.getName());
            obj.put("video_user_cover", user.getImage());
            array.add(obj);
        }
        JSONObject ret = new JSONObject();
        ret.put("videos", array);
        return ResponseUtil.success(ret);
    }
}
